const Exercise = require('../models/Exercise');
const Card = require('../models/Card');
const User = require('../models/User');

/**
 * @desc    获取所有练习题
 * @route   GET /api/exercises
 * @access  私有
 */
const getExercises = async (req, res) => {
  try {
    // 支持分页
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const skip = (page - 1) * limit;

    // 支持过滤
    const filter = {};
    if (req.query.type) filter.type = req.query.type;
    
    // 处理难度过滤
    if (req.query.difficulty) {
      // 字符串难度值到数字的映射
      const difficultyMap = {
        'EASY': 2,
        'MEDIUM': 3,
        'HARD': 4
      };
      
      // 如果是字符串难度值，使用映射转换
      if (difficultyMap[req.query.difficulty] !== undefined) {
        filter.difficulty = difficultyMap[req.query.difficulty];
      } else {
        // 尝试直接解析为数字
        const difficultyNum = parseInt(req.query.difficulty);
        if (!isNaN(difficultyNum)) {
          filter.difficulty = difficultyNum;
        }
      }
    }
    
    if (req.query.cardId) filter.cardId = req.query.cardId;

    // 获取练习题总数
    const total = await Exercise.countDocuments(filter);

    // 获取练习题
    const exercises = await Exercise.find(filter)
      .populate('cardId', 'title chapter')
      .sort({ createdAt: -1 })
      .skip(skip)
      .limit(limit);

    res.json({
      exercises,
      page,
      pages: Math.ceil(total / limit),
      total
    });
  } catch (error) {
    console.error('获取练习题时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取单个练习题
 * @route   GET /api/exercises/:id
 * @access  私有
 */
const getExerciseById = async (req, res) => {
  try {
    const exercise = await Exercise.findById(req.params.id)
      .populate('cardId', 'title content chapter difficulty tags');

    if (!exercise) {
      return res.status(404).json({ message: '练习题不存在' });
    }

    res.json(exercise);
  } catch (error) {
    console.error('获取练习题详情时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    更新练习题
 * @route   PUT /api/exercises/:id
 * @access  私有
 */
const updateExercise = async (req, res) => {
  try {
    const { question, options, answer, difficulty, explanation } = req.body;
    const exercise = await Exercise.findById(req.params.id);

    if (!exercise) {
      return res.status(404).json({ message: '练习题不存在' });
    }

    // 更新练习题信息
    if (question) exercise.question = question;
    if (options) exercise.options = options;
    if (answer) exercise.answer = answer;
    if (difficulty) exercise.difficulty = difficulty;
    if (explanation) exercise.explanation = explanation;

    exercise.updatedAt = Date.now();
    await exercise.save();

    res.json({
      message: '练习题更新成功',
      exercise
    });
  } catch (error) {
    console.error('更新练习题时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    删除练习题
 * @route   DELETE /api/exercises/:id
 * @access  私有
 */
const deleteExercise = async (req, res) => {
  try {
    const exercise = await Exercise.findById(req.params.id);

    if (!exercise) {
      return res.status(404).json({ message: '练习题不存在' });
    }

    await exercise.remove();

    res.json({ message: '练习题删除成功' });
  } catch (error) {
    console.error('删除练习题时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    检查练习题答案
 * @route   POST /api/exercises/:id/check
 * @access  私有
 */
const checkExerciseAnswer = async (req, res) => {
  try {
    const { id } = req.params;
    const { userAnswer } = req.body;
    
    const exercise = await Exercise.findById(id);
    if (!exercise) {
      return res.status(404).json({ message: '练习题不存在' });
    }

    // 检查答案是否正确
    let isCorrect = false;
    
    // 根据不同题型检查答案
    switch (exercise.type) {
      case 'choice':
        // 选择题直接比较选项ID
        isCorrect = userAnswer === exercise.answer;
        break;
      case 'fill':
        // 填空题进行不区分大小写的比较
        isCorrect = userAnswer.toLowerCase() === exercise.answer.toLowerCase();
        break;
      case 'code':
        // 代码题可能需要更复杂的比较逻辑，这里简化处理
        isCorrect = userAnswer.trim() === exercise.answer.trim();
        break;
      default:
        break;
    }

    // 记录用户的练习结果
    if (req.user) {
      const user = await User.findById(req.user._id);
      
      if (user) {
        user.exercises.push({
          exerciseId: exercise._id,
          correct: isCorrect,
          userAnswer,
          attemptDate: Date.now()
        });
        
        await user.save();
      }
    }

    res.json({
      correct: isCorrect,
      correctAnswer: exercise.answer,
      explanation: exercise.explanation
    });
  } catch (error) {
    console.error('检查练习题答案时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取随机练习题
 * @route   GET /api/exercises/random
 * @access  私有
 */
const getRandomExercises = async (req, res) => {
  try {
    const { count = 5, type, difficulty, chapter } = req.query;
    
    // 构建查询条件
    const filter = {};
    if (type) filter.type = type;
    if (difficulty) filter.difficulty = parseInt(difficulty);
    
    // 如果指定了章节，需要先查找该章节的卡片
    if (chapter) {
      const cards = await Card.find({ chapter }).select('_id');
      const cardIds = cards.map(card => card._id);
      filter.cardId = { $in: cardIds };
    }

    // 随机获取指定数量的练习题
    const exercises = await Exercise.aggregate([
      { $match: filter },
      { $sample: { size: parseInt(count) } }
    ]);

    // 填充关联的卡片信息
    const populatedExercises = await Exercise.populate(exercises, {
      path: 'cardId',
      select: 'title chapter'
    });

    res.json(populatedExercises);
  } catch (error) {
    console.error('获取随机练习题时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取用户的练习统计
 * @route   GET /api/exercises/stats
 * @access  私有
 */
const getUserExerciseStats = async (req, res) => {
  try {
    const user = await User.findById(req.user._id);
    
    if (!user) {
      return res.status(404).json({ message: '用户不存在' });
    }

    // 计算统计数据
    const stats = {
      totalAttempts: user.exercises.length,
      correctAttempts: user.exercises.filter(e => e.correct).length,
      accuracyRate: 0,
      byType: {
        choice: { total: 0, correct: 0, rate: 0 },
        fill: { total: 0, correct: 0, rate: 0 },
        code: { total: 0, correct: 0, rate: 0 }
      },
      recentAttempts: []
    };

    // 计算准确率
    if (stats.totalAttempts > 0) {
      stats.accuracyRate = (stats.correctAttempts / stats.totalAttempts) * 100;
    }

    // 获取最近的练习记录
    stats.recentAttempts = await Promise.all(
      user.exercises
        .sort((a, b) => b.attemptDate - a.attemptDate)
        .slice(0, 10)
        .map(async (attempt) => {
          const exercise = await Exercise.findById(attempt.exerciseId)
            .populate('cardId', 'title chapter');
          
          return {
            date: attempt.attemptDate,
            correct: attempt.correct,
            userAnswer: attempt.userAnswer,
            exercise: exercise ? {
              id: exercise._id,
              question: exercise.question,
              type: exercise.type,
              card: exercise.cardId ? {
                id: exercise.cardId._id,
                title: exercise.cardId.title,
                chapter: exercise.cardId.chapter
              } : null
            } : null
          };
        })
    );

    // 按类型统计
    for (const attempt of user.exercises) {
      const exercise = await Exercise.findById(attempt.exerciseId);
      if (exercise) {
        const type = exercise.type;
        if (stats.byType[type]) {
          stats.byType[type].total += 1;
          if (attempt.correct) {
            stats.byType[type].correct += 1;
          }
        }
      }
    }

    // 计算各类型准确率
    for (const type in stats.byType) {
      if (stats.byType[type].total > 0) {
        stats.byType[type].rate = (stats.byType[type].correct / stats.byType[type].total) * 100;
      }
    }

    res.json(stats);
  } catch (error) {
    console.error('获取用户练习统计时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

module.exports = {
  getExercises,
  getExerciseById,
  updateExercise,
  deleteExercise,
  checkExerciseAnswer,
  getRandomExercises,
  getUserExerciseStats
}; 